/**
 * MainPanel.java
 * 
 * Copyright (C) 2012 - Thibault BUREL
 * 
 * This file is part of MathDraft.
 *
 * MathDraft is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * MathDraft is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with MathDraft.  If not, see <http://www.gnu.org/licenses/>
 *  
 */
package drk.mathdraft.ihm;

import drk.mathdraft.StudiedProposition;
import drk.mathdraft.ihm.tree.ExpressionTree;
import drk.mathdraft.proposition.*;
import drk.mathdraft.proposition.builder.NaturalNotation;
import drk.mathdraft.proposition.builder.SyntaxException;
import drk.mathdraft.rules.*;

import java.awt.*;

import javax.swing.*;


public class MainPanel extends JPanel
{
	private static final long serialVersionUID = 1L;
	
	protected ExpressionTree ep;
	protected RightPanel     rp;
	private static volatile  MainPanel instance = null;
	
	private MainPanel ()
	{
		super();

		ep = new ExpressionTree();
		rp = new RightPanel(ep);
		
		ep.setPreferredSize(new Dimension(250,480));
		rp.setPreferredSize(new Dimension(750,480));
		
		ep.setVisible(true);
		rp.setVisible(true);
		
		
		this.setLayout(new BoxLayout(this,BoxLayout.X_AXIS));

		this.add(ep);
		this.add(rp);
	}
	
	/**
	 * Rule1 : a = b \Rightarrow a + c = b + c
	 */
	public void applyRule1() throws RuleException
	{
			if (rp.getDirect() == true)
			{
				drk.mathdraft.rules.Rule1.applyDirectRule1
					(rp.getFirstNode(), getLineCommand());
			}
			else
			{
				javax.swing.JOptionPane.showMessageDialog(null,"Not yet implemented !");
			}
			StudiedProposition.getInstance().forceUpdate();
	}
	
	/**
	 * Rule2 : a = b \Rightarrow a * c = b * c
	 */
	public void applyRule2()
	{
		Proposition p = rp.getFirstNode();
		
		if(p instanceof Equality) 
		{
			Proposition e;
			try
			{
				e = NaturalNotation.fromNaturalNotation (getLineCommand());
				((Equality)p).mulSameExpEachMembers(e);
				StudiedProposition.getInstance().forceUpdate();
			}
			catch (SyntaxException exc)
			{
				// TODO
			}
		}
	}
	
	/**
	 * Rule3 : \frac{0}{c} = 0
	 */
	public void applyRule3()
	{
		Proposition p = rp.getFirstNode();
		
		if (rp.getDirect() == true)
		{
			if(p instanceof Division) 
			{
				if (((Division)p).getFirst() instanceof drk.mathdraft.proposition.Number)
				{
					if(((drk.mathdraft.proposition.Number)((Division)p).getFirst()).getName().equals("0"))
					{
						Proposition root = p.getParent();
						Proposition z = new drk.mathdraft.proposition.Number(0);

						if(root != null)
						{
							root.replaceChild(p, z);
						}
						else
						{
							StudiedProposition.getInstance().setProposition(z);
						}
					}
				}
			}
		}
		else
		{
			if(p instanceof drk.mathdraft.proposition.Number) 
			{
				if(((drk.mathdraft.proposition.Number)p).getName().equals("0"))
				{
					Proposition root = p.getParent();
					
					Proposition e;
					try
					{
						e = NaturalNotation.fromNaturalNotation (getLineCommand());
						Proposition n = new Division(p, e);
						
						if(root != null)
						{
							root.replaceChild(p, n);
						}
						else
						{
							StudiedProposition.getInstance().setProposition(n);
						}
					}
					catch (SyntaxException exc)
					{
						// TODO
					}	
				}
			}
		}
		StudiedProposition.getInstance().forceUpdate();
	}
	
	public final static MainPanel getInstance()
	{
		if (MainPanel.instance == null)
		{
			synchronized(MainPanel.class)
			{
				if (MainPanel.instance == null)
				{
					MainPanel.instance = new MainPanel();
				}
			}
		}
		return MainPanel.instance;
	}
	
	public String getLineCommand()
	{
		return rp.getLineCommand();
	}
	
	public Proposition getSelectedNode()
	{
		return ep.getSelectedNode();
	}
}